"""
邢不行™️ 策略分享会
仓位管理实盘框架

版权所有 ©️ 邢不行
微信: xbx6660

本代码仅供个人学习使用，未经授权不得复制、修改或用于商业用途。

Author: 邢不行
"""
import os
import time
from pathlib import Path

from core.utils.path_kit import get_folder_path

# ====================================================================================================
# ** 数据配置 **
# ====================================================================================================
data_config = dict(
    realtime_data_path='********填写服务器上数据中心data目录的绝对路径********',  # 实盘数据路径
    min_kline_num=168,  # 最少上市多久，不满该K线根数的币剔除，即剔除刚刚上市的新币。168：标识168个小时，即：7*24
    get_kline_num=3500,  # 获取多少根K线。这里跟策略日频和小时频影响。日线策略，代表999根日线k。小时策略，代表999根小时k
    reserved_cache=['select'],  # 用于缓存控制：['select']表示只缓存选币结果，不缓存其他数据，['all']表示缓存所有数据。
    # 目前支持选项：
    # - select: 选币结果pkl
    # - strategy: 大杂烩中策略选币pkl
    # - all: 无视上述配置细节，包含 `all` 就代表我全要
    # 缓存东西越多，硬盘消耗越大，对于参数比较多硬盘没那么大的童鞋，可以在这边设置
    clean_start=True,  # 启动是是否删除缓存。如果你不了解这个选项，保持为True，滥用缓存会有灾难性后果。
)
# 全局报错机器人通知
# - 创建企业微信机器人 参考帖子: https://bbs.quantclass.cn/thread/10975
# - 配置案例  https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxxxxxxxxxxxxx
error_webhook_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='
is_debug = True  # debug模式。模拟运行程序，不会去下单

# ====================================================================================================
# ** 账户配置 **
# ====================================================================================================
account_name = '仓位管理演示账户'
account_config = {
    # 交易所API配置
    'apiKey': '',
    'secret': '',
    # ++++ 分钟偏移功能 ++++
    # 支持任意时间开始的小时级别K线
    "hour_offset": '30m',  # 分钟偏移设置，可以自由设置时间，配置必须是kline脚本中interval的倍数。默认：0m，表示不偏移。15m，表示每个小时偏移15m下单。
    # ++++ 企业微信机器人功能 ++++
    "wechat_webhook_url": error_webhook_url,
}

# ====================================================================================================
# ** 策略细节配置 **
# 案例策略，需要自己探索，不保证可用
# ====================================================================================================
strategy_name = '流动性大杂烩择时'  # 当前账户运行策略的名称。可以自己任意取
strategy_config = {
    'name': 'FixedRatioStrategy',  # *必填。使用什么策略，这里是轮动策略
    'hold_period': '24H',  # *必填。聚合后策略持仓周期。目前回测支持日线级别、小时级别。例：1H，6H，3D，7D......
    'params': {
        'cap_ratios': [1 / 2, 1 / 2]
    }
}
# 策略池
strategy_pool = [
    # 流动性多头
    dict(
        name='流动性多头大杂烩（择时MA5x24）',
        strategy_list=[
            {
                # 策略名称。与strategy目录中的策略文件名保持一致。
                "strategy": "Strategy_流动性多头",
                "offset_list": range(0, 24, 6),
                "hold_period": "24H",
                "is_use_spot": True,
                # 资金权重。程序会自动根据这个权重计算你的策略占比，具体可以看1.8的直播讲解
                'cap_weight': 1,
                'long_cap_weight': 1,
                'short_cap_weight': 1,
                'long_select_coin_num': x,
                'short_select_coin_num': 'long_nums',
                # 选币因子信息列表，用于`2_选币_单offset.py`，`3_计算多offset资金曲线.py`共用计算资金曲线
                "factor_list": [
                    (y, True, z, 1),  # 多头因子名（和factors文件中相同），排序方式，参数，权重。
                ],
                "filter_list": [
                    ('PctChange', z, 'pct:<0.8')
                ],
                "use_custom_func": False  # 使用系统内置因子计算、过滤函数
            }
            for x in [0.1] for y in ['QuoteVolumeMean'] for z in [48, 96, 192, 384, 768]
        ],
        re_timing={'name': 'MovingAverage', 'params': [5 * 24]}  # 可选，配置再择时策略
    ),
    dict(
        name='流动性多头大杂烩（择时MA55x24）',
        strategy_list=[
            {
                # 策略名称。与strategy目录中的策略文件名保持一致。
                "strategy": "Strategy_流动性多头",
                "offset_list": range(0, 24, 6),
                "hold_period": "24H",
                "is_use_spot": True,
                # 资金权重。程序会自动根据这个权重计算你的策略占比，具体可以看1.8的直播讲解
                'cap_weight': 1,
                'long_cap_weight': 1,
                'short_cap_weight': 1,
                'long_select_coin_num': x,
                'short_select_coin_num': 'long_nums',
                # 选币因子信息列表，用于`2_选币_单offset.py`，`3_计算多offset资金曲线.py`共用计算资金曲线
                "factor_list": [
                    (y, True, z, 1),  # 多头因子名（和factors文件中相同），排序方式，参数，权重。
                ],
                "filter_list": [
                    ('PctChange', z, 'pct:<0.8')
                ],
                "use_custom_func": False  # 使用系统内置因子计算、过滤函数
            }
            for x in [0.1] for y in ['QuoteVolumeMean'] for z in [48, 96, 192, 384, 768]
        ],
        re_timing={'name': 'MovingAverage', 'params': [55 * 24]}  # 可选，配置再择时策略
    )
]

black_list = ['BTC-USDT', 'ETH-USDT']  # 拉黑名单，永远不会交易。不喜欢的币、异常的币。例：LUNA-USDT, 这里与实盘不太一样，需要有'-'
white_list = []  # 如果不为空，即只交易这些币，只在这些币当中进行选币。例：LUNA-USDT, 这里与实盘不太一样，需要有'-'

# ====================================================================================================
# ** 模拟器细节配置 **
# ====================================================================================================
simulator_config = dict(
    # 模拟下单回测设置
    initial_usdt=1_0000,  # 初始资金
    leverage=1,  # 杠杆数。我看哪个赌狗要把这里改成大于1的。高杠杆如梦幻泡影。不要想着一夜暴富，脚踏实地赚自己该赚的钱。
    margin_rate=0.05,  # 维持保证金率，净值低于这个比例会爆仓
    swap_c_rate=5 / 10000,  # 合约手续费(包含滑点)
    spot_c_rate=1 / 1000,  # 现货手续费(包含滑点)
    swap_min_order_limit=5,  # 合约最小下单量。最小不能低于5
    spot_min_order_limit=10,  # 现货最小下单量。最小不能低于10
    avg_price_col='avg_price_1m',  # 用于模拟计算的平均价，预处理数据使用的是1m，'avg_price_1m'表示1分钟的均价, 'avg_price_5m'表示5分钟的均价。
)

# ====================================================================================================
# ** 文件系统相关配置 **
# - 获取一些全局路径
# - 自动创建缺失的文件夹们
# ====================================================================================================
# 获取目录位置，不存在就创建目录
data_path = get_folder_path('data', as_path_type=True)

# 获取目录位置，不存在就创建目录
flag_path = get_folder_path('data', 'flag', as_path_type=True)

# 获取目录位置，不存在就创建目录
order_path = get_folder_path('data', 'order', as_path_type=True)

# 获取目录位置，不存在就创建目录
runtime_folder = get_folder_path('data', 'runtime', as_path_type=True)

# 预处理数据路径
bmac_data_path = Path(data_config['realtime_data_path']) / 'preprocess_1h_resample'
# 比重信息的路径
bmac_exginfo_path = Path(data_config['realtime_data_path']) / 'exginfo'

backtest_path = get_folder_path('data', '回测结果', as_path_type=True)
backtest_iter_path = get_folder_path('data', '遍历结果', as_path_type=True)

snapshot_path = get_folder_path('data', 'snapshot', as_path_type=True)

# ====================================================================================================
# ** 回测全局设置 **
# 这些设置是客观事实，基本不会影响到回测的细节
# ====================================================================================================
job_num = max(os.cpu_count() - 1, 1)  # 回测并行数量
# job_num = 2  # 回测并行数量

# ==== factor_col_limit 介绍 ====
factor_col_limit = 64  # 内存优化选项，一次性计算多少列因子。64是 16GB内存 电脑的典型值
# - 数字越大，计算速度越快，但同时内存占用也会增加。
# - 该数字是在 "因子数量 * 参数数量" 的基础上进行优化的。
#   - 例如，当你遍历 200 个因子，每个因子有 10 个参数，总共生成 2000 列因子。
#   - 如果 `factor_col_limit` 设置为 64，则计算会拆分为 ceil(2000 / 64) = 32 个批次，每次最多处理 64 列因子。
# - 对于16GB内存的电脑，在跑含现货的策略时，64是一个合适的设置。
# - 如果是在16GB内存下跑纯合约策略，则可以考虑将其提升到 128，毕竟数值越高计算速度越快。
# - 以上数据仅供参考，具体值会根据机器配置、策略复杂性、回测周期等有所不同。建议大家根据实际情况，逐步测试自己机器的性能极限，找到适合的最优值。

# 获取当前服务器时区，距离UTC 0点的偏差
utc_offset = int(time.localtime().tm_gmtoff / 60 / 60)  # 如果服务器在上海，那么utc_offset=8

# ====================================================================================================
# ** 交易所配置 **
# ====================================================================================================
# 如果使用代理 注意替换IP和Port
proxy = {}
# proxy = {'http': 'http://127.0.0.1:7890', 'https': 'http://127.0.0.1:7890'}  # 如果你用clash的话
exchange_basic_config = {
    'timeout': 30000,
    'rateLimit': 30,
    'enableRateLimit': False,
    'options': {
        'adjustForTimeDifference': True,
        'recvWindow': 10000,
    },
    'proxies': proxy,
}

# 稳定币信息，不参与交易的币种
stable_symbol = ['BKRW', 'USDC', 'USDP', 'TUSD', 'BUSD', 'FDUSD', 'DAI', 'EUR', 'GBP', 'USBP', 'SUSD', 'PAXG', 'AEUR',
                 'EURI']

if bmac_data_path.exists() is False or bmac_exginfo_path.exists() is False:
    print('⚠️ 请准确配置实盘数据中心的路径，并且启动数据中心，完成实盘数据初始化后，再运行本脚本')
    exit()
